//
// Created by 86176 on 2021/11/3.
//

#ifndef CHENYUENEW_IOACCEPTOR_H
#define CHENYUENEW_IOACCEPTOR_H
#include <stdio.h>
#include<iostream>
#include<time.h>
#include <Winsock2.h>
#include <mswsock.h>
#include "DefaultFilterChain.h"
#include "Session.h"
#include "IoHandler.h"
//#include <map>
#include <set>
#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "Mswsock.lib")


class IoAcceptor {
protected:
    //std::map<int,Session*> sessions;
    //空闲的结构记录，也就是我们的资源池
    //std::set<Session*>  m_FreeSessionSet;
    std::set<Session*>  m_WorkSessionSet;
    std::set<Session*>  m_FreeSessionSet;
    std::set<CIOCPBuffer*>  m_FreeCIOCPBuffer;
    CIOCPBuffer* m_pFreeBufferList;
    long m_nFreeBufferCount;
    long m_nFreeSessionCount;
    long m_nWorkSessionCount;

    CRITICAL_SECTION m_WorkSessionSetLock;
    CRITICAL_SECTION m_FreeSessionSetLock;
    CRITICAL_SECTION m_FreeBufferListLock;
    CRITICAL_SECTION m_FreeContextListLock;

    //服务器的监听session
    Session* serveSession;
    int index;

    //抛出的Accept请求集合。
    std::set<CIOCPBuffer*> m_PendingAccepts;
    long m_nPendingAcceptCount;
    CRITICAL_SECTION m_PendingAcceptsLock;

    //记录连接记录
    std::set<CIOCPBuffer*>  m_ConnectionSet;
    int m_nCurrentConnection;
    CRITICAL_SECTION m_ConnectionListLock;

    //服务器限制
    int m_nInitialAccepts;  //初始投递accpet数
    int m_nInitialReads;    //初始读时间投递数
    int m_nMaxAccepts;      //最大投递accpet数
    int m_nMaxSends;        //每个套接字上最大的在等待投递数
    int m_nMaxFreeBuffers;  //缓冲池最大IOBuffter数量
    int m_nMaxFreeSessions; //session池最大session数量
    int m_nMaxConnections;  //最大同时在线的Session数


public:
    Session* temp;
    DefaultFilterChain *defaultFilterChain;
    Session *getServeSession() const;

    void setServeSession(Session *serveSession);

    Session * registerSession(int id);
    Session *getSession(int id);
    bool destroySession(int id);
    int PostAccept(HANDLE hPort);
    int PostRecv(Session *session);
    BOOL PostSend(Session *session);

public:
    IoAcceptor();
    ~IoAcceptor();
    virtual bool bind(char *port,char *ip)=0;
    bool bind();
    void addFilterChainLast(FilterChain *filterChain) const;
    void setHandler(IoHandler *ioHandler);

protected:
    CIOCPBuffer* AllocateBuffer(int nLen);
    void ReleaseBuffer(Session *session, CIOCPBuffer *pBuffer);
    Session* AllocateSession();
    void ReleaseSession(Session *session);
    // 取得下一个要读取的
    CIOCPBuffer *GetNextReadBuffer(Session *IocpEvent, CIOCPBuffer *pBuffer);
    //直接取得下一个
    CIOCPBuffer *GetNextReadBufferDir(Session *IocpEvent);
    //拼接消息
    bool SpliceMessage(Session *IocpEvent,CIOCPBuffer *pBuffer);
};


#endif //CHENYUENEW_IOACCEPTOR_H
